home *** CD-ROM | disk | FTP | other *** search
/ Computer Music Interactif…cial Edition 1999 Winter / cd 3.iso / mac / Mac / Shares / Midishare™1.68 / Development Tools / Sources Examples / Other MidiShare Examples / simpleSeq / simpleSeq.c next >
Encoding:
C/C++ Source or Header  |  1992-05-18  |  5.1 KB  |  194 lines  |  [TEXT/MPS ]

  1. /*====================== A MIDI SHARE TOOL  (© GRAME 92) =====================
  2.  
  3. NAME
  4.       SimpleSeq -- a simple MidiShare MPW tool
  5.  
  6. SYNOPSIS
  7.       SimpleSeq
  8.       cmds :    Q <enter> to quit
  9.                 R <enter> to record
  10.                 S <enter> to stop recording or playing
  11.                 P <enter> to play
  12. DESCRIPTION
  13.     "SimpleSeq" open a MidiShare session, wait for user commands to record and
  14.     play sequences, and then close the MidiShare session
  15.  
  16. ===============================================================================*/
  17.  
  18.  
  19. #include <String.h>
  20. #include <StdLib.h>
  21. #include <Stdio.h>
  22. #include <MidiShare.h>
  23. #include <CursorCtl.h>
  24.  
  25.  
  26.  
  27. //----------------------------- utilities ---------------------------------
  28.  
  29. long lopt (char *argv[], char *name, long def) 
  30. {
  31.     int    i;
  32.     for (i=0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
  33.     return def;
  34. }
  35.  
  36. int flag (char *argv[], char *name) 
  37. {
  38.     int    i;
  39.     for (i=0; argv[i]; i++) if (!strcmp(argv[i], name)) return 1;
  40.     return 0;
  41. }
  42.  
  43. void Wait(long d) 
  44. {    d += MidiGetTime();
  45.     while (MidiGetTime() < d) SpinCursor(1);
  46. }
  47.  
  48.  
  49.  
  50. //----------------------------- TSequencer ---------------------------------
  51.  
  52.  
  53. // definition of a TSequencer
  54.  
  55. #define idle     0
  56. #define playing 1
  57. #define recording 2
  58.  
  59. typedef struct TSequencer {
  60.     short        ref;                                    // MidiShare client reference number
  61.     short         state;                                    // state idle, playing or recording
  62.     MidiSeqPtr    seq;                                    // the sequence of MidiShare events
  63.     MidiEvPtr    task;                                    // a pointer to the real time play task
  64. } TSequencer;
  65.  
  66. void OpenSeq(TSequencer * s);                            // Init and open a MidiShare session
  67. void CloseSeq(TSequencer * s);                            // Stop and close the MidiShare session
  68. void StopSeq(TSequencer * s);                            // Stop recording or playing
  69. void PlaySeq(TSequencer * s);                            // Start playing
  70. void RecSeq(TSequencer * s);                            // Start recording
  71.  
  72. pascal void    NullRcv (short refNum);                        // MidiShare receive alarm when idle or playing
  73. pascal void    RecRcv (short refNum);                        // MidiShare receive alarm when recording
  74. pascal void    PlayTask (long date, short refNum, TSequencer * s, MidiEvPtr e, long);
  75.                                                         // RealTime task to play the sequence
  76.  
  77. // implementation of a TSequencer
  78.  
  79. void OpenSeq(TSequencer * s)
  80. {
  81.     s->ref = MidiOpen("\pSimpleSeq");                    // open the MidiShare session
  82.     
  83.     s->state = idle;                                    // first state is idle
  84.     s->seq = MidiNewSeq();                                // create an empty sequence
  85.     s->task = 0;                                        // no task at the momment
  86.     
  87.     MidiSetInfo(s->ref, s);                                // save a pointer to itself for future uses
  88.     MidiSetRcvAlarm(s->ref, NullRcv);                    // install a receive alarm to delete incomming events
  89.     
  90.     MidiConnect(s->ref, 0, 1);                            // connect to physical midi outputs
  91.     MidiConnect(0, s->ref, 1);                            // connect from physical midi inputs
  92. }
  93.  
  94. void CloseSeq(TSequencer * s)                
  95. {
  96.     StopSeq(s);                                            // stop current activities
  97.     MidiFreeSeq(s->seq);                                // free the sequence
  98.     MidiClose(s->ref);                                    // close the session
  99. }
  100.  
  101. void StopSeq(TSequencer * s)
  102. {
  103.     printf("Stop\n");
  104.     switch (s->state) {
  105.         case playing :                                    // stop playing
  106.             MidiForgetTask(&s->task);                    //   forget the current play task
  107.             s->state = idle;
  108.             break;
  109.         case recording :                                // stop recording
  110.             MidiSetRcvAlarm(s->ref, NullRcv);            //     install the Null receive alarm
  111.             s->state = idle;
  112.             break;
  113.     }
  114. }
  115.  
  116. void PlaySeq(TSequencer * s)
  117. {
  118.     MidiEvPtr e;
  119.     
  120.     StopSeq(s);                                            // stop current activities
  121.     printf("Play\n");
  122.     if (e = First(s->seq)) {                            // if sequence not empty
  123.         s->state = playing;                        
  124.         PlayTask(MidiGetTime(), s->ref, s, e, 0);         // call the playTask
  125.     }
  126. }
  127.  
  128. void RecSeq(TSequencer * s)
  129. {
  130.     StopSeq(s);                                            // stop current activities
  131.     printf("Record\n");
  132.     s->state = recording;
  133.     MidiClearSeq(s->seq);                                // clear the sequence
  134.     MidiSetRcvAlarm(s->ref, RecRcv);                    // install the recording receive alarm
  135. }
  136.     
  137. pascal void NullRcv (short ref)
  138. {
  139.     MidiEvPtr e;
  140.     while (e = MidiGetEv(ref)) MidiFreeEv(e);            // delete all the received events
  141. }
  142.  
  143. pascal void RecRcv (short ref)
  144. {
  145.     TSequencer * s;
  146.     MidiEvPtr e;
  147.     
  148.     s = (TSequencer *) MidiGetInfo(ref);                // get a pointer to itself
  149.     while (e = MidiGetEv(ref)) {
  150.         MidiSendIm(ref, MidiCopyEv(e));
  151.         MidiAddSeq(s->seq, e);    // add to the sequence all the received events
  152.     }
  153. }
  154.  
  155. pascal void    PlayTask (long date, short r, TSequencer * s, MidiEvPtr e, long d)
  156. {
  157.     d = Date(e);                                        // remember the date of the current event to play
  158.     while (e && (Date(e) == d)) {                        // for all the events at this date
  159.         MidiSendIm(r, MidiCopyEv(e));                    // send a copy
  160.         e = Link(e);                                    // go to next event
  161.     }
  162.     if (e) {                                            // if not the end, schedule the task for next event
  163.         s->task = MidiTask((TaskPtr)PlayTask, date+Date(e)-d, r, (long)s, (long)e, 0);
  164.     } else {
  165.         s->task = 0;                                    // set the task pointer to NIL
  166.         s->state = idle;                                // change the state to idle
  167.     }
  168. }
  169.     
  170.  
  171.  
  172.  
  173. //-------------------------------- main ------------------------------------
  174.  
  175. main( int, char **)
  176. {
  177.     char        c;
  178.     TSequencer    mySequencer;
  179.     
  180.     InitCursorCtl(0);
  181.     
  182.     OpenSeq(&mySequencer);
  183.     
  184.     while ((c = getchar()) && c != 'q' && c != 'Q')  switch (c) {
  185.  
  186.         case 'P': case 'p': PlaySeq(&mySequencer); break;
  187.         case 'R': case 'r': RecSeq(&mySequencer); break;
  188.         case 'S': case 's': StopSeq(&mySequencer); break;
  189.     }
  190.     
  191.     CloseSeq(&mySequencer);
  192. }
  193.  
  194.